using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace NHTrace
{
	public class WebBrowserEx : System.Windows.Forms.WebBrowser
	{
		#region WebBrowserSiteEx Class
		protected class WebBrowserSiteEx : System.Windows.Forms.WebBrowser.WebBrowserSite, IServiceProvider, IInternetSecurityManager
		{
			private static Guid IID_IInternetSecurityManager = 
				Marshal.GenerateGuidForType(typeof(IInternetSecurityManager));

			private WebBrowserEx _webBrowser;

			public WebBrowserSiteEx(WebBrowserEx webBrowser) : base(webBrowser)
			{
				_webBrowser = webBrowser;
			}

			#region IServiceProvider Members
			public int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject)
			{
				if(guidService == IID_IInternetSecurityManager &&
					riid == IID_IInternetSecurityManager)
				{
					ppvObject = Marshal.GetComInterfaceForObject(this,
						typeof(IInternetSecurityManager));
					return Constants.S_OK;
				}
				ppvObject = IntPtr.Zero;
				return Constants.E_NOINTERFACE;
			}
			#endregion IServiceProvider Members

			#region IInternetSecurityManager Members
			public unsafe int SetSecuritySite(void* pSite)
			{
			    return Constants.INET_E_DEFAULT_ACTION;
			}

			public unsafe int GetSecuritySite(void** ppSite)
			{
			    return Constants.INET_E_DEFAULT_ACTION;
			}

			public unsafe int MapUrlToZone(string url, int* pdwZone, int dwFlags)
			{
        *pdwZone = 0;//local -> "Local", "Intranet", "Trusted", "Internet", "Restricted"
        return Constants.S_OK;
			}

			public unsafe int GetSecurityId(string url, byte* pbSecurityId, int* pcbSecurityId, int dwReserved)
			{
        return Constants.INET_E_DEFAULT_ACTION;
			}

			public unsafe int ProcessUrlAction(string url, int dwAction, byte* pPolicy, int cbPolicy,
				byte* pContext, int cbContext, int dwFlags, int dwReserved)
			{
        *((int*)pPolicy) = (int)Constants.UrlPolicy.URLPOLICY_ALLOW;
        return Constants.S_OK;
			}

			public unsafe int QueryCustomPolicy(string pwszUrl, void* guidKey, byte** ppPolicy, int* pcbPolicy, byte* pContext, int cbContext, int dwReserved)
			{
			    return Constants.INET_E_DEFAULT_ACTION;
			}

			public int SetZoneMapping(int dwZone, string lpszPattern, int dwFlags)
			{
			    return Constants.INET_E_DEFAULT_ACTION;
			}

			public unsafe int GetZoneMappings(int dwZone, void** ppenumString, int dwFlags)
			{
			    return Constants.INET_E_DEFAULT_ACTION;
			}
			#endregion

		}
		#endregion WebBrowserSiteEx Class

		private WebBrowserSiteEx _site;

		public WebBrowserEx()
		{
		}

		protected override WebBrowserSiteBase CreateWebBrowserSiteBase()
		{
			if(_site == null)
				_site = new WebBrowserSiteEx(this);
			return _site;
		}

	}

  [ComImport]
  [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  [Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
  public interface IServiceProvider
  {
    [PreserveSig]
    int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject);
  }

  [ComImport]
  [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  [Guid("79eac9ee-baf9-11ce-8c82-00aa004ba90b")]
  public interface IInternetSecurityManager
  {
    [PreserveSig]
    unsafe int SetSecuritySite(void* pSite);
    [PreserveSig]
    unsafe int GetSecuritySite(void** ppSite);
    [PreserveSig]
    unsafe int MapUrlToZone([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, int* pdwZone, [In] int dwFlags);
    [PreserveSig]
    unsafe int GetSecurityId([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, byte* pbSecurityId, int* pcbSecurityId, int dwReserved);
    [PreserveSig]
    unsafe int ProcessUrlAction([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, int dwAction, byte* pPolicy, int cbPolicy, byte* pContext, int cbContext, int dwFlags, int dwReserved);
    [PreserveSig]
    unsafe int QueryCustomPolicy([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, void* guidKey, byte** ppPolicy, int* pcbPolicy, byte* pContext, int cbContext, int dwReserved);
    [PreserveSig]
    int SetZoneMapping(int dwZone, [In, MarshalAs(UnmanagedType.LPWStr)] string lpszPattern, int dwFlags);
    [PreserveSig]
    unsafe int GetZoneMappings(int dwZone, void** ppenumString, int dwFlags);
  }

  public static class Constants
  {
    public const int S_OK = 0;
    public const int E_NOINTERFACE = unchecked((int)0x80004002);
    public const int INET_E_DEFAULT_ACTION = unchecked((int)0x800C0011);
    public enum UrlPolicy
    {
      URLPOLICY_ALLOW = 0,
      URLPOLICY_QUERY = 1,
      URLPOLICY_DISALLOW = 3,
    }
  }
}
